package org.com.lcuiot.handler;

import org.com.lcuiot.database.dto.Result;
import org.com.lcuiot.database.entity.User;
import org.com.lcuiot.service.UserExampleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.Optional;

import static org.springframework.web.reactive.function.BodyInserters.fromValue;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.notFound;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

/**
 * @author gaoge
 * @since 2022/10/22 07:33
 */
@RestController
public class AcceptDataExampleHandler {
    private static final Logger logger = LoggerFactory.getLogger(AcceptDataExampleHandler.class);
    private final UserExampleService userExampleService;

    @Autowired
    public AcceptDataExampleHandler(UserExampleService userExampleService) {
        this.userExampleService = userExampleService;
    }

    @Bean
    public RouterFunction<ServerResponse> acceptDataRouter() {
        logger.info("Init Controller accept data");
        return route()
                .GET("/example_accept_data", this::acceptDataExampHandler)
                .POST("/example_accept_data_push", this::pushDataExampleHandler)
                .DELETE("/example_accept_data/{id}", this::deleteDataExampleHandler)
                .PATCH("/example_accept_data/{id}", this::patchDataExampleHandler)
                .build();
    }

    private Mono<ServerResponse> patchDataExampleHandler(ServerRequest request) {
        logger.debug("patch data in handler");
        String id = request
                .pathVariable("id");
        String name = request.queryParam("name").orElse(null);
        Optional<User> u = userExampleService.patchUser(Long.parseLong(id), name);
        Result<Object> r = Result.build();
        if(u.isPresent()) {
            User uu = u.get();
            r.setData(uu);
            return ok().body(fromValue(r));
        } else {
            return notFound().build();
        }
    }

    private Mono<ServerResponse> deleteDataExampleHandler(ServerRequest request) {
        logger.debug("Delete data in handler");
        String id = request
                .pathVariable("id");
        Optional<User> u = userExampleService.deleteUser(Long.parseLong(id));
        if(u.isPresent()) {
            return ok()
                    .body(fromValue("delete succ"));
        } else {
            return notFound().build();
        }
    }

    private Mono<ServerResponse> acceptDataExampHandler(ServerRequest request) {
        logger.debug("debug out put in handler");
        String name = request
                .queryParam("name")
                .orElse("World");
        String message = String.format("Hello, %s!", name);
        userExampleService.addUser(name);

        return ok()
                .body(fromValue(message));
    }

    private Mono<ServerResponse> pushDataExampleHandler(ServerRequest request) {
        logger.debug("debug push handler");
        String name = request
                .queryParam("name")
                .orElse("World");
        String message = String.format("Hello, %s!", name);
        Optional<User> uu = userExampleService.addUser(name);
        if(uu.isPresent()) {
            message = uu.get().getUsername();
        }

        return ok()
                .body(fromValue(uu));
    }
}
